from utils.BaseModel import BaseTable
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.conf import settings

# 用户表
class User(AbstractUser):
    phone = models.CharField(max_length=11, unique=True, verbose_name='手机号')
    password = models.CharField(max_length=128, verbose_name='密码')
    username = models.CharField(max_length=128, unique=True, verbose_name='用户名')

    def __str__(self):
        return f"{self.username} ({self.phone})"

    class Meta:
        db_table = 'user'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

# 第三方登录表
class ThirdLogin(BaseTable):
    user = models.ForeignKey(
        User, 
        on_delete=models.CASCADE, 
        related_name='third_logins', 
        verbose_name='用户',
        null=True,  # 允许为空
        blank=True  # 允许在表单中为空
    )
    method = models.CharField(max_length=100, verbose_name='登录方式')
    third_id = models.CharField(max_length=100, verbose_name='第三方ID')
    
    class Meta:
        db_table = 'third_login'
        verbose_name = '第三方登录'
        verbose_name_plural = verbose_name
        
    def __str__(self):
        return f"{self.user.username if self.user else '未关联用户'}的{self.method}登录"

# 实名认证表
class RealNameAuth(BaseTable):
    AUTH_STATUS_CHOICES = (
        ('pending', '待审核'),
        ('approved', '已通过'),
        ('rejected', '已拒绝'),
    )

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='real_name_auth', verbose_name='用户')
    real_name = models.CharField(max_length=50, verbose_name='真实姓名')
    id_card = models.CharField(max_length=18, verbose_name='身份证号')
    id_card_front = models.URLField(max_length=255, verbose_name='身份证正面照片URL')
    auth_status = models.CharField(max_length=10, choices=AUTH_STATUS_CHOICES, default='pending', verbose_name='认证状态')
    auth_time = models.DateTimeField(null=True, blank=True, verbose_name='认证通过时间')
    reject_reason = models.CharField(max_length=200, null=True, blank=True, verbose_name='拒绝原因')

    class Meta:
        db_table = 'real_name_auth'
        verbose_name = '实名认证信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f"{self.user.username}的实名认证信息"

    def save(self, *args, **kwargs):
        if self.auth_status == 'approved':
            UserProfile.objects.filter(user=self.user).update(
                is_verified=True,
                real_name=self.real_name,
                id_card=self.id_card
            )
        else:
            UserProfile.objects.filter(user=self.user).update(is_verified=False)
        super().save(*args, **kwargs)

# 用户详细信息表
class UserProfile(BaseTable):
    USER_TYPE_CHOICES = (
        ('tenant', '租客'),
        ('landlord', '房东'),
        ('admin', '管理员'),
    )

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile', verbose_name='用户')
    real_name = models.CharField(max_length=50, blank=True, null=True, verbose_name='真实姓名')
    id_card = models.CharField(max_length=18, blank=True, null=True, verbose_name='身份证号')
    email = models.EmailField(max_length=100, blank=True, null=True, verbose_name='邮箱')
    avatar_url = models.URLField(max_length=255, blank=True, null=True, verbose_name='头像URL')
    user_type = models.CharField(max_length=10, choices=USER_TYPE_CHOICES, default='tenant', verbose_name='用户类型')
    status = models.BooleanField(default=True, verbose_name='账号状态')
    is_verified = models.BooleanField(default=False, verbose_name='是否实名认证')

    class Meta:
        db_table = 'user_profile'
        verbose_name = '用户详细信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f"{self.user.username}的详细信息"

class HouseType(models.Model):
    name = models.CharField(max_length=50, verbose_name='房源类型名称')
    class Meta:
        db_table = 'house_type'
        verbose_name = '房源类型'
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.name

# 房源表
class HouseListing(BaseTable):
    HOUSE_STATUS_CHOICES = (
        ('available', '可租'),
        ('rented', '已租'),
        ('offline', '下线'),
    )

    ORIENTATION_CHOICES = (
        ('east', '东'),
        ('south', '南'),
        ('west', '西'),
        ('north', '北'),
        ('southeast', '东南'),
        ('southwest', '西南'),
        ('northeast', '东北'),
        ('northwest', '西北'),
    )

    DECORATION_CHOICES = (
        ('simple', '简装'),
        ('medium', '中等装修'),
        ('deluxe', '精装'),
        ('luxury', '豪华装修'),
    )

    landlord = models.ForeignKey('users.User', on_delete=models.CASCADE, related_name='house_listings', verbose_name='房东')
    title = models.CharField(max_length=100, verbose_name='标题')
    description = models.TextField(verbose_name='描述')
    address = models.CharField(max_length=255, verbose_name='地址')
    city = models.CharField(max_length=50, verbose_name='城市')
    district = models.CharField(max_length=50, verbose_name='区域')
    room_count = models.IntegerField(verbose_name='房间数')
    bathroom_count = models.IntegerField(verbose_name='卫生间数')
    area = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='面积(平方米)')
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='月租金')
    deposit = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='押金')
    house_type = models.CharField(max_length=50, verbose_name='户型')
    floor = models.IntegerField(verbose_name='楼层')
    total_floor = models.IntegerField(verbose_name='总楼层')
    orientation = models.CharField(max_length=20, choices=ORIENTATION_CHOICES, verbose_name='朝向')
    decoration_type = models.CharField(max_length=50, choices=DECORATION_CHOICES, verbose_name='装修程度')
    facilities = models.JSONField(null=True, blank=True, verbose_name='配套设施')
    images = models.JSONField(null=True, blank=True, verbose_name='房源图片URL数组')
    status = models.CharField(max_length=20, choices=HOUSE_STATUS_CHOICES, default='available', verbose_name='房源状态')
    type = models.ForeignKey(HouseType, on_delete=models.CASCADE, verbose_name='房源类型')
    views_count = models.IntegerField(default=0, verbose_name='浏览次数')
    views = models.ManyToManyField('users.User', through='HouseView', related_name='viewed_houses', verbose_name='浏览记录')

    class Meta:
        db_table = 'house_listing'
        verbose_name = '房源信息'
        verbose_name_plural = verbose_name
        indexes = [
            models.Index(fields=['city', 'district']),
            models.Index(fields=['price']),
            models.Index(fields=['area']),
            models.Index(fields=['status']),
            models.Index(fields=['views_count']),
        ]

    def __str__(self):
        return self.title

# 房源浏览记录表
class HouseView(BaseTable):
    user = models.ForeignKey('users.User', on_delete=models.CASCADE, verbose_name='用户')
    house = models.ForeignKey(HouseListing, on_delete=models.CASCADE, verbose_name='房源')
    view_time = models.DateTimeField(auto_now_add=True, verbose_name='浏览时间')

    class Meta:
        db_table = 'house_view'
        verbose_name = '房源浏览记录'
        verbose_name_plural = verbose_name
        unique_together = ('user', 'house')  # 一个用户对同一个房源只记录一次浏览

    def save(self, *args, **kwargs):
        if not self.pk:  # 如果是新记录
            self.house.views_count += 1
            self.house.save()
        super().save(*args, **kwargs)


class UserHouseInteraction(models.Model):
    """用户房源交互记录模型"""
    user = models.ForeignKey('users.User', on_delete=models.CASCADE, verbose_name='用户')
    house = models.ForeignKey('HouseListing', on_delete=models.CASCADE, verbose_name='房源')
    count = models.IntegerField(default=0, verbose_name='交互次数')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'tb_user_house_interaction'
        verbose_name = '用户房源交互'
        verbose_name_plural = verbose_name
        unique_together = ('user', 'house')  # 确保用户和房源的组合是唯一的

    def __str__(self):
        return f"{self.user.username} - {self.house.title} ({self.count}次)"

# from django.contrib.auth.models import AbstractUser
from utils.BaseModel import BaseTable
# Create your models here.
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.core.validators import MinValueValidator



class HouseTransaction(BaseTable):
    # 图片字段 - 新增
    property_image = models.ImageField(
        '房产图片',
        upload_to='property_images/%Y/%m/%d/',
        null=True,
        blank=True,
        help_text='上传房产展示图片'
    )
    # 基础信息
    community = models.CharField('小区名称', max_length=100)
    layout = models.CharField('户型', max_length=20)
    direction = models.CharField('朝向', max_length=10)  # 如"南向"

    # 楼层信息
    FLOOR_LEVEL_CHOICES = [
        ('low', '低楼层'),
        ('middle', '中楼层'),
        ('high', '高楼层'),
    ]
    floor_level = models.CharField('楼层类型', max_length=10, choices=FLOOR_LEVEL_CHOICES)
    total_floors = models.PositiveIntegerField('总楼层数', validators=[MinValueValidator(1)])

    # 面积与价格
    area = models.FloatField('面积(㎡)', validators=[MinValueValidator(0.1)])
    total_price = models.FloatField('总价(万元)', validators=[MinValueValidator(0.1)])
    unit_price = models.FloatField('单价(元/㎡)', validators=[MinValueValidator(1)])

    # 交易信息
    contract_date = models.DateField('签约日期')

    # 经纪人信息
    agent_name = models.CharField('经纪人姓名', max_length=50)
    agent_title = models.CharField('经纪人身份', max_length=50, default='房源成交经纪人')

    # 自动记录时间戳
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)

    def __str__(self):
        return f"{self.community} - {self.layout} - {self.total_price}万"

    class Meta:
        verbose_name = '房产成交记录'
        verbose_name_plural = '房产成交记录'
        ordering = ['-contract_date']


class ResidentialCommunity(BaseTable):
    # 图片字段 - 新增
    property_image = models.ImageField(
        '房产图片',
        upload_to='property_images/%Y/%m/%d/',
        null=True,
        blank=True,
        help_text='上传房产展示图片'
    )
    # 小区基本信息
    name = models.CharField('小区名称', max_length=100)
    region = models.CharField('区域', max_length=50)  # 如"新北区"
    sub_region = models.CharField('板块', max_length=50)  # 如"三井"

    # 建设信息
    completion_year = models.PositiveIntegerField('竣工年份', validators=[
        MinValueValidator(1900)
    ])

    # 市场信息
    average_price = models.DecimalField(
        '均价(元/m²)',
        max_digits=8,
        decimal_places=2,
        validators=[MinValueValidator(0)]
    )
    properties_for_sale = models.PositiveIntegerField('在售房源数量', default=0)

    # 系统字段
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)

    def __str__(self):
        return f"{self.name} ({self.region}-{self.sub_region})"

    class Meta:
        verbose_name = '住宅小区'
        verbose_name_plural = '住宅小区'
        ordering = ['-average_price']
        indexes = [
            models.Index(fields=['region', 'sub_region']),
            models.Index(fields=['completion_year']),
        ]




# 学校找房表
class School(BaseTable):
    # 基本信息
    name = models.CharField('学校名称', max_length=100)
    school_type = models.CharField('学校类型', max_length=50, default='公办')
    district = models.CharField('所属区域', max_length=50)

    # 位置信息
    distance = models.FloatField('距离(km)', help_text='单位：公里')

    # 扩展信息
    address = models.CharField('详细地址', max_length=200, blank=True, null=True)
    established_year = models.PositiveIntegerField('建校年份', blank=True, null=True)
    description = models.TextField('学校简介', blank=True, null=True)

    # 系统字段
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '学校信息'
        verbose_name_plural = '学校信息'
        ordering = ['name']
        indexes = [
            models.Index(fields=['district']),
            models.Index(fields=['school_type']),
        ]

class Cart(models.Model):
    user = models.ForeignKey('users.User', on_delete=models.CASCADE)
    house = models.ForeignKey(HouseListing, on_delete=models.CASCADE)
    is_select = models.BooleanField(default=False)
    def __str__(self):
        return self.user.username
    class Meta:
        verbose_name = '购物车'
        verbose_name_plural = verbose_name


from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone


class Contract(models.Model):
    CONTRACT_TYPES = [
        ('RENT', '租赁合同'),
        ('SELL', '买卖合同'),
    ]
    
    id = models.AutoField(primary_key=True)
    contract_type = models.CharField(max_length=10, choices=CONTRACT_TYPES, verbose_name='合同类型')
    contract_number = models.CharField(max_length=50, unique=True, verbose_name='合同编号')
    house = models.ForeignKey('HouseListing', on_delete=models.CASCADE, verbose_name='房源')
    landlord = models.ForeignKey('users.User', on_delete=models.CASCADE, related_name='landlord_contracts', verbose_name='房东')
    tenant = models.ForeignKey('users.User', on_delete=models.CASCADE, related_name='tenant_contracts', verbose_name='租客/买家')
    total_amount = models.DecimalField(max_digits=12, decimal_places=2, verbose_name='合同总金额')
    deposit = models.DecimalField(max_digits=12, decimal_places=2, verbose_name='押金/定金')
    contract_file = models.FileField(upload_to='contracts/', null=True, blank=True, verbose_name='合同文件')
    annexes = models.FileField(upload_to='contract_annexes/', null=True, blank=True, verbose_name='合同附件')
    remarks = models.TextField(null=True, blank=True, verbose_name='备注')
    effective_time = models.DateField(verbose_name='生效时间')
    expire_time = models.DateField(verbose_name='到期时间')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '合同'
        verbose_name_plural = '合同'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.contract_number} - {self.get_contract_type_display()}"


class RentContract(models.Model):
    PAYMENT_CYCLES = [
        ('MONTHLY', '月付'),
        ('QUARTERLY', '季付'),
        ('SEMIANNUALLY', '半年付'),
        ('ANNUALLY', '年付'),
    ]
    
    id = models.AutoField(primary_key=True)
    contract = models.OneToOneField(Contract, on_delete=models.CASCADE, related_name='rent_details', verbose_name='主合同')
    rent = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='租金')
    payment_cycle = models.CharField(max_length=20, choices=PAYMENT_CYCLES, verbose_name='支付周期')
    payment_due_day = models.IntegerField(verbose_name='每期支付日')
    start_date = models.DateField(verbose_name='起租日期')
    end_date = models.DateField(verbose_name='终止日期')
    grace_period = models.IntegerField(default=3, verbose_name='宽限期(天)')
    early_termination_allowed = models.BooleanField(default=True, verbose_name='允许提前终止')
    early_termination_fee = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='提前终止违约金')

    class Meta:
        verbose_name = '租赁合同详情'
        verbose_name_plural = '租赁合同详情'

    def __str__(self):
        return f"租赁合同详情 - {self.contract.contract_number}"


class SellContract(models.Model):
    PAYMENT_METHODS = [
        ('FULL', '全款'),
        ('MORTGAGE', '按揭'),
        ('INSTALLMENT', '分期付款'),
    ]
    
    id = models.AutoField(primary_key=True)
    contract = models.OneToOneField(Contract, on_delete=models.CASCADE, related_name='sell_details', verbose_name='主合同')
    house_price = models.DecimalField(max_digits=12, decimal_places=2, verbose_name='房屋售价')
    payment_method = models.CharField(max_length=20, choices=PAYMENT_METHODS, verbose_name='付款方式')
    down_payment = models.DecimalField(max_digits=12, decimal_places=2, verbose_name='首付金额')
    mortgage_bank = models.CharField(max_length=100, null=True, blank=True, verbose_name='按揭银行')
    mortgage_amount = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True, verbose_name='按揭金额')
    transfer_date = models.DateField(verbose_name='过户日期')
    property_handover_date = models.DateField(verbose_name='交房日期')

    class Meta:
        verbose_name = '买卖合同详情'
        verbose_name_plural = '买卖合同详情'

    def __str__(self):
        return f"买卖合同详情 - {self.contract.contract_number}"


class ContractPaymentRecord(models.Model):
    """合同付款记录"""

    PAYMENT_TYPE_CHOICES = (
        ('RENT', '租金'),
        ('DEPOSIT', '押金'),
        ('DOWN_PAYMENT', '首付'),
        ('INSTALLMENT', '分期款'),
        ('FINAL_PAYMENT', '尾款'),
        ('OTHER', '其他'),
    )

    PAYMENT_STATUS_CHOICES = (
        ('PENDING', '待支付'),
        ('PAID', '已支付'),
        ('OVERDUE', '逾期'),
        ('REFUNDED', '已退款'),
    )

    contract = models.ForeignKey(Contract, on_delete=models.CASCADE, related_name='payments', verbose_name='关联合同')
    payment_type = models.CharField(max_length=20, choices=PAYMENT_TYPE_CHOICES, verbose_name='付款类型')
    amount = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='金额')
    due_date = models.DateField(verbose_name='应支付日期')
    actual_payment_date = models.DateField(null=True, blank=True, verbose_name='实际支付日期')
    payment_status = models.CharField(max_length=20, choices=PAYMENT_STATUS_CHOICES, default='PENDING',
                                      verbose_name='支付状态')
    payment_method = models.CharField(max_length=50, null=True, blank=True, verbose_name='支付方式')
    transaction_id = models.CharField(max_length=100, null=True, blank=True, verbose_name='交易流水号')
    remark = models.CharField(max_length=255, null=True, blank=True, verbose_name='备注')

    class Meta:
        db_table = 'contract_payment_record'
        verbose_name = '合同付款记录'
        verbose_name_plural = verbose_name


class ContractChangeLog(models.Model):
    """合同变更日志"""

    CHANGE_TYPE_CHOICES = (
        ('AMENDMENT', '条款修改'),
        ('EXTENSION', '租期延长'),
        ('TERMINATION', '提前终止'),
        ('OTHER', '其他变更'),
    )

    contract = models.ForeignKey(Contract, on_delete=models.CASCADE, related_name='change_logs',
                                 verbose_name='关联合同')
    change_type = models.CharField(max_length=20, choices=CHANGE_TYPE_CHOICES, verbose_name='变更类型')
    change_time = models.DateTimeField(auto_now_add=True, verbose_name='变更时间')
    changer = models.ForeignKey('users.User', on_delete=models.SET_NULL, null=True, related_name='contract_changes',
                                verbose_name='变更人')
    old_value = models.TextField(null=True, blank=True, verbose_name='变更前值')
    new_value = models.TextField(null=True, blank=True, verbose_name='变更后值')
    reason = models.TextField(verbose_name='变更原因')

    class Meta:
        db_table = 'contract_change_log'
        verbose_name = '合同变更日志'
        verbose_name_plural = verbose_name

class Order(models.Model):
    """订单模型"""
    orderno = models.CharField(max_length=64, unique=True, verbose_name='订单号')
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name='用户')
    zprice = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='支付金额')
    order_type = models.CharField(max_length=32, verbose_name='订单类型')
    status = models.CharField(max_length=32, default='待支付', verbose_name='订单状态')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'order'
        verbose_name = '订单'
        verbose_name_plural = verbose_name
        ordering = ['-create_time']

    def __str__(self):
        return f"{self.orderno} - {self.status}"


